#include <EventSender.hpp>
#include <EventReceiver.hpp>
#include <Event.hpp>
#include <EventDispatcher.hpp>
#include <string>
#include <iostream>
using namespace std;

class MySender:public EventSender
{
public:
  string name;
};
MySender the_sender;

class MyReceiver:public EventReceiver
{
public:
  string name;
};

void produceHisFuck(const Event& e)
{
MySender *s = dynamic_cast<MySender*>( e.getSender() );
MyReceiver *r = dynamic_cast<MyReceiver*>( e.getReceiver() );
cerr << " ----\nhis fuck is called! \n"
 << "Event-Type:" << e.getType() << endl
 << "Sender-name:" << s->name << endl
 << "Receiver-name:" << r->name << endl;
}
void produceHerFuck(const Event& e)
{
MySender *s = dynamic_cast<MySender*>( e.getSender() );
MyReceiver *r = dynamic_cast<MyReceiver*>( e.getReceiver() );
cerr << " ----\nher fuck is called! \n"
 << "Event-Type:" << e.getType() << endl
 << "Sender-name:" << s->name << endl
 << "Receiver-name:" << r->name << endl;
}


class MyDispatcher:public EventDispatcher
{
public:
  string name;
};
  void produceAllFuck( const Event& e )
  {
    MyDispatcher *sme = dynamic_cast<MyDispatcher*>( e.getSender() );
    MyDispatcher *rme = dynamic_cast<MyDispatcher*>( e.getReceiver() );
    cerr << " ----\nall fuck is called! \n" ;
    cerr << "Event-Type:" << e.getType() << endl;
    cerr << "Sender-name:" << sme->name << endl;
    cerr << "Receiver-name:" << rme->name << endl;
  }
  
  void produceAnyFuck( const Event& e )
  {
    MySender *s = dynamic_cast<MySender*>( e.getSender() );
    MyDispatcher *r = dynamic_cast<MyDispatcher*>( e.getReceiver() );
    cerr << " ----\nany fuck is called! \n"; 
	  cerr << "Event-Type:" << e.getType() << endl;
	  cerr << "Sender-name:" << s->name << endl;
	  cerr << "Receiver-name:" << r->name << endl;
  }

MyDispatcher the_dispatcher;

void dispatch_event( MySender &the_sender )
{
  cerr << "=======================================" << endl;
  Event e(0);
  the_sender.eventHappen(e);
  e.eventID = 1;
  the_sender.eventHappen(e);
  the_dispatcher.eventHappen(e);
}

int main()
{
  the_sender.name = "sender-No0";
  the_dispatcher.name = "dispatch-No0";
  MyReceiver the_receiver0, the_receiver1;
  the_receiver0.name = "receiver-No0";
  the_receiver1.name = "receiver-No1";

  the_receiver0.listenEvent( 0, THE_SENDER(&the_sender), THE_HANDLER(&produceHisFuck) );
  the_receiver0.listenEvent( 1, THE_SENDER(&the_sender), THE_HANDLER(&produceHerFuck) );
  the_dispatcher.addListener( 1, &the_sender, &produceAnyFuck );

  the_receiver1.listenEvent( 1, THE_SENDER(&the_sender), THE_HANDLER(&produceHisFuck) );

  dispatch_event( the_sender );
  the_receiver0.nolistenEvent( 0, THE_SENDER(&the_sender), THE_HANDLER(&produceHisFuck) );
  the_dispatcher.listenMyEvent( 1, THE_HANDLER(&produceAllFuck) );
	
  dispatch_event( the_sender );
}

